package com._21cn.framework.base.db.mybatis;

import com._21cn.framework.base.db.BaseDao;
import com._21cn.framework.flip.PageList;
import com._21cn.framework.flip.PageHashMap;
import com._21cn.framework.flip.PageTurn;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.*;

/**
 * Created by 司徒海富 on 2017/2/3.
 */
public class BaseDaoMybatis<T> extends SqlSessionDaoSupport implements BaseDao<T> {

    private String nameSpace = "";

    public static final int DEFAULT_PAGE_SIZE = 100;   //如果调用分页方法的pageSize等于或小于0时，系统采用默认的pageSize为100

    public String getNameSpace() {
        return nameSpace;
    }

    public void setNameSpace(String nameSpace) {
        this.nameSpace = nameSpace;
    }

    //========================================查 询==========================================================
    public T selectById(Object id) {
        return (T) getSqlSession().selectOne(getNameSpace() + ".selectById", id);
    }

    public PageList selectByMap(Map<String, Object> params, int pageNo, int pageSize, boolean doCount) {
        return (PageList<T>)query4PageList( getNameSpace() + ".selectByMap", params, pageNo, pageSize, doCount );
    }

    public PageList<T> selectByMap(Map<String, Object> params, int pageNo, int pageSize) {
        return selectByMap(params, pageNo, pageSize, true);
    }

    public int selectCountByMap(Map<String, Object> params) {
        Integer count = ( Integer ) getSqlSession().selectOne(getNameSpace() + ".selectByMap_count", params);
        return count.intValue();
    }

    //========================================添 加==========================================================
    public void insert(T object) {
        getSqlSession().insert(getNameSpace() + ".insert", object);
    }

    public int batchInsert(Collection<T> objects) {
        if( objects == null || objects.isEmpty() )
            return 0;
        return getSqlSession().insert(getNameSpace() + ".batchInsert", objects);
    }

    public int batchInsert(T... objects) {
        if(objects !=null && objects.length >= 0 )
            return batchInsert( Arrays.asList( objects ) );
        return 0;
    }

    //========================================更 新==========================================================
    public int updateByMap(Map<String, Object> params) {
        return getSqlSession().update( getNameSpace() + ".updateByMap", params );
    }

    public int update(T object) {
        return getSqlSession().update( getNameSpace() + ".updateById", object );
    }

    public int batchUpdate(Collection<T> objects) {
        if( objects == null || objects.isEmpty() )
            return 0;
        return getSqlSession().update(getNameSpace() + ".batchUpdate", objects);
    }

    public int batchUpdate(T... objects) {
        if(objects !=null && objects.length >= 0 )
            return batchUpdate( Arrays.asList( objects ) );
        return 0;
    }

    //========================================删 除==========================================================
    public int deleteByMap(Map<String, Object> params) {
        return getSqlSession().delete( getNameSpace() + ".deleteByMap", params );
    }

    public int deleteById(Object id) {
        return getSqlSession().delete( getNameSpace() + ".deleteById", id );
    }

    public int batchDeleteById(Collection<?> objects) {
        if( objects == null || objects.isEmpty() )
            return 0;
        return getSqlSession().delete(getNameSpace() + ".batchDeleteById", objects);
    }

    public int batchDeleteById(Object[] objects) {
        if(objects !=null && objects.length >= 0 )
            return batchDeleteById( Arrays.asList( objects ) );
        return 0;
    }

    //========================================其 它==========================================================
    /**
     * 根据条件获取分页list
     */
    protected PageList query4PageList( String sqlMapId, Map<String, Object> params, int page, int pageSize ) {
        return query4PageList( sqlMapId, params, new PageTurn( page, pageSize ), true );
    }

    protected PageList query4PageList( String sqlMapId, Map<String, Object> params, int page, int pageSize, boolean doCount ) {
        return query4PageList( sqlMapId, params, new PageTurn( page, pageSize ), doCount );
    }

    protected PageList query4PageList( String sqlMapId, Map<String, Object> params, PageTurn turn, boolean doCount ) {
        PageTurn retTurn = initParamAndPageTurn( sqlMapId + "_count", params, turn, doCount );
        PageList pagelist = new PageList();
        pagelist.setPageTurn( retTurn );
        if( retTurn.getRowCount().intValue() > 0 ) {
            try {
                List list = this.getSqlSession().selectList(sqlMapId, params);
                pagelist.addAll( list );
            }catch( Exception e ) {
                e.printStackTrace();
            }
        }
        return pagelist;
    }

    /**
     * 根据条件获取分页hashMap
     */
    protected PageHashMap query4PageHashMap(String sqlMapId, Map<String, Object> params, int page, int pageSize, String keyProperty) {
        return this.query4PageHashMap(sqlMapId, params, new PageTurn(page, pageSize), true, keyProperty);
    }

    protected PageHashMap query4PageHashMap(String sqlMapId, Map<String, Object> params, int page, int pageSize, boolean reCount, String keyProperty) {
        return this.query4PageHashMap(sqlMapId, params, new PageTurn(page, pageSize), reCount, keyProperty);
    }

    protected PageHashMap query4PageHashMap(String sqlMapId, Map<String, Object> params, PageTurn turn, boolean reCount, String keyProperty) {
        PageTurn retTurn = this.initParamAndPageTurn(sqlMapId + "_count", params, turn, reCount);
        PageHashMap pageHashMap = new PageHashMap();
        pageHashMap.setPageTurn(retTurn);
        if(retTurn.getRowCount().intValue() > 0) {
            try {
                Map map = this.getSqlSession().selectMap(sqlMapId, params, keyProperty);
                pageHashMap.putAll(map);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return pageHashMap;
    }

    private PageTurn initParamAndPageTurn( String sqlMapId, Map<String, Object> params, PageTurn turn, boolean doCount ){
        PageTurn retTurn = new PageTurn();
        int total = -1;
        if( doCount || turn.getPageSize().intValue() == 0 )
            total = queryCount( sqlMapId, params );
        if( total < 0 )
            total = turn.getRowCount().intValue();
        if( total > 0 ) {
            int tempPageSize = turn.getPageSize().intValue();
            if( tempPageSize <= 0 )
                tempPageSize = total > DEFAULT_PAGE_SIZE ? DEFAULT_PAGE_SIZE : total;
            retTurn.initWithPage( turn.getPage().intValue(), tempPageSize, total );
            params.put( "pageTurn", retTurn );
            params.put( "pageTurnStartRow", retTurn.getStart() );
            params.put( "pageTurnEndRow", retTurn.getEnd() );
        }
        return retTurn;
    }

    /**
     * @param sqlMapId sql语句id
     * @param param 查询参数
     * @return count结果
     */
    protected int queryCount( String sqlMapId, Map<String, Object> param ) {
        int total = -1;
        try {
            total = ((Integer)getSqlSession().selectOne(sqlMapId, param)).intValue();
        } catch( Exception e ) {
            e.printStackTrace();
        }
        return total;
    }

    /**
     * 获取数据库系统时间
     * @return
     */
    public Date getCurrentTime() {
        return (Date)getSqlSession().selectOne("BASE_DAO.getCurrentTime", null);
    }

    /**
     * 获取数据库中某个表的记录总数
     */
    public int getRowCountOfTable( String tableName ) {
        return ((Integer)getSqlSession().selectOne("BASE_DAO.getRowCountOfTable", tableName)).intValue();
    }

}
